package com.chinamobile.iot.mqtt.spi.impl.security;

import com.chinamobile.iot.config.MqttConfiguration;
import com.chinamobile.iot.mqtt.spi.security.ISslContextCreator;
import com.chinamobile.iot.utils.CertificateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.cert.X509Certificate;

/**
 * Created by stayfool on 2016/12/7.
 */
@Component
public class JKSSslContextCreator implements ISslContextCreator {

    private Logger log = LoggerFactory.getLogger(getClass());

    @Autowired
    private MqttConfiguration config;

    private boolean valid;

    @Override
    public SSLContext initSSLContext() {
        log.info("begin initialize ssl context");
        try {
            if (!checkJKS()){
                return null;
            }
            KeyManagerFactory kmf = initKmf();
            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(kmf.getKeyManagers(), null, null);
            return sslContext;
        } catch (Exception e) {
            log.error("initialize ssl context failed：{}", e);
        }
        return null;
    }

    // 加载秘钥管理器
    private KeyManagerFactory initKmf() throws Exception {
        String jksAbsolutePath = getAbsolutePath(config.getSsl().getJks());
        InputStream in = new FileInputStream(new File(jksAbsolutePath));
        //KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
        KeyStore ks = KeyStore.getInstance("JKS");
        ks.load(in, config.getSsl().getPassword().toCharArray());
        KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        kmf.init(ks, config.getSsl().getPassword().toCharArray());
        return kmf;
    }

    private boolean checkJKS() throws Exception {
        String jksAbsolutePath = getAbsolutePath(config.getSsl().getJks());
        String cerAbsolutePath = getAbsolutePath(config.getSsl().getCer());
        File jksFile = new File(jksAbsolutePath);
        if (!jksFile.exists()) {
            log.info("the jks file is not on the path!");
            return false;
//            KeyStore ks = CertificateUtil.createKeyStore();
//            FileOutputStream os = new FileOutputStream(new File(jksAbsolutePath));
//            ks.store(os, config.getSsl().getPassword().toCharArray());
//
//            os = new FileOutputStream(new File(cerAbsolutePath));
//            X509Certificate cer = (X509Certificate) ks.getCertificate(CertificateUtil.ALIAS);
//
//            os.write(cer.getEncoded());
//            os.flush();
//            os.close();
        }
        return true;
    }

    private String getAbsolutePath(String path) {
        if (isAbsolutePath(path))
            return path;
        String classpath = Thread.currentThread().getContextClassLoader().getResource("").getPath();
        path = path.substring(path.indexOf(":") + 1);
        return classpath + File.separator + path;
    }

    private boolean isAbsolutePath(String path) {
        return new File(path).isAbsolute();
    }
}
